package com.lch.base.http;

import android.util.Log;

import com.lch.base.http.callback.ICallbackBase;
import com.lch.base.http.exception.ExceptionHandler;
import com.lch.base.http.exception.RetryWhenNetworkException;
import com.trello.rxlifecycle2.LifecycleProvider;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
import retrofit2.Response;

/**
 * 请求回来的数据处理工具
 *
 * @author lee(29487113@qq.com) on 18/2/4
 */

public class RxTranslateUtils {

    //下面文章可以做总结
    //http://m.blog.csdn.net/vansbelove/article/details/53886356
    //http://www.jianshu.com/p/59c3d6bb6a6b
    //http://www.jianshu.com/p/0cd258eecf60
    //http://blog.csdn.net/wbwjx/article/details/52082020

    /**
     * ObservableTransformer 作用于整个流,Func是一个操作符,作用于数据项
     *
     * @param <T>
     * @return
     */
    public static <T> ObservableTransformer<Response<ResponseBody>, T> translate(final ICallbackBase callback, final LifecycleProvider mLifecycleProvider) {
        return new ObservableTransformer<Response<ResponseBody>, T>() {
            @Override
            public ObservableSource apply(Observable upstream) {
                Observable observable = upstream;
                //判断外部有没有传入生命周期，就有绑定
                if (mLifecycleProvider != null) {
                    observable = upstream.compose(mLifecycleProvider.bindToLifecycle());
                }
                return observable
                        .map(new ServerResponseTranslateFunc<T>(callback)) //进行数据转换
                        .retryWhen(new RetryWhenNetworkException())  //失败后的retry配置, 放到onErrorResumeNext前面，不然onErrorResumeNext会重新定义Exception
                        .onErrorResumeNext(new HttpResponseFunc()) //拦截服务器返回的错误
                        .subscribeOn(Schedulers.io())   // subscribeOn() 指定的就是发射事件的线程
                        .unsubscribeOn(Schedulers.io()) //取消订阅制定线程
                        .observeOn(AndroidSchedulers.mainThread());  //observerOn 指定的就是订阅者接收事件的线程。
            }
        };
    }


    /**
     * 对服务器返回的数据进行解析，返回结构是BaseResult<T>
     *
     * @param <T>
     */
    private static class ServerResponseTranslateFunc<T> implements Function<Response<ResponseBody>, T> {
        private ICallbackBase mCallback;

        public ServerResponseTranslateFunc(ICallbackBase callback) {
            mCallback = callback;
        }

        @Override
        public T apply(Response<ResponseBody> response) throws Exception {
            if (mCallback != null) {
                return (T) mCallback.onHandleResponse(response);
            } else {
                return null; //会抛空指针
            }
        }
    }

    /**
     * 错误处理fun
     * 对所有错误进行统一解析
     */
    private static class HttpResponseFunc implements Function<Throwable, Observable> {

        @Override
        public Observable apply(Throwable throwable) throws Exception {
            Log.i("lch1", "线程HttpResponseFunc错误处理" + " => " + Thread.currentThread().getName());
            Log.i("lch1", "HttpResponseFunc" + " => " + throwable);
            return Observable.error(ExceptionHandler.handleException(throwable));
        }
    }

}
